home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / GAS_1_38.ARJ / VMS_DBG.C < prev    next >
C/C++ Source or Header  |  1990-11-13  |  38KB  |  1,126 lines

  1. #include <stdio.h>
  2. #include "as.h"
  3. #include "struc-symbol.h"
  4. #include "symbols.h"
  5. #include "objrecdef.h"
  6. #include <stab.h>
  7.  
  8. /* This file contains many of the routines needed to output debugging info into
  9.  * the object file that the VMS debugger needs to understand symbols.  These
  10.  * routines are called very late in the assembly process, and thus we can be
  11.  * fairly lax about changing things, since the GSD and the TIR sections have
  12.  * already been output.
  13.  */
  14.  
  15. /* We need this info to cross correlate between the stabs def for a symbol and
  16.  * the actual symbol def.  The actual symbol def contains the psect number and
  17.  * offset, which is needed to declare a variable to the debugger for global
  18.  * and static variables
  19.  */
  20. struct VMS_Symbol {
  21.     struct VMS_Symbol *Next;
  22.     struct symbol *Symbol;
  23.     int Size;
  24.     int Psect_Index;
  25.     int Psect_Offset;
  26.     };
  27. extern struct VMS_Symbol *VMS_Symbols;
  28.  
  29. enum advanced_type {BASIC,POINTER,ARRAY,ENUM,STRUCT,UNION,FUNCTION,VOID,UNKNOWN};
  30.  
  31. /* this structure contains the information from the stabs directives, and the
  32.  * information is filled in by VMS_typedef_parse.  Everything that is needed
  33.  * to generate the debugging record for a given symbol is present here.
  34.  * This could be done more efficiently, using nested struct/unions, but for now
  35.  * I am happy that it works.
  36.  */
  37. struct VMS_DBG_Symbol{
  38.     struct VMS_DBG_Symbol * next;
  39.     enum advanced_type advanced;    /* description of what this is */
  40.     int dbx_type;    /* this record is for this type */
  41.     int type2;    /* For advanced types this is the type referred to.
  42.                 i.e. the type a pointer points to, or the type
  43.                 of object that makes up an array */
  44.     int VMS_type;    /* Use this type when generating a variable def */
  45.     int index_min;    /* used for arrays - this will be present for all */
  46.     int index_max;    /* entries, but will be meaningless for non-arrays */
  47.     int data_size;    /* size in bytes of the data type.  For an array, this
  48.                is the size of one element in the array */
  49.     int struc_numb; /* Number of the structure/union/enum - used for ref */
  50. };
  51.  
  52. struct VMS_DBG_Symbol *VMS_Symbol_type_list={(struct VMS_DBG_Symbol*) NULL};
  53.  
  54. /* we need this structure to keep track of forward references to
  55.  * struct/union/enum that have not been defined yet.  When they are ultimately
  56.  * defined, then we can go back and generate the TIR commands to make a back
  57.  * reference.
  58.  */
  59.  
  60. struct forward_ref{
  61.     struct forward_ref * next;
  62.     int dbx_type;
  63.     int struc_numb;
  64.     char resolved;
  65.     };
  66.  
  67. struct forward_ref * f_ref_root={(struct forward_ref*) NULL};
  68.  
  69. static char * symbol_name;
  70. static structure_count=0;
  71.  
  72. /* this routine converts a number string into an integer, and stops when it
  73.  * sees an invalid character the return value is the address of the character 
  74.  * just past the last character read.  No error is generated.
  75.  */
  76. static char * cvt_integer(char* str,int * rtn){
  77.     int ival, neg;
  78.         neg = *str == '-' ? ++str, -1 : 1;
  79.         ival=0;    /* first get the number of the type for dbx */
  80.         while((*str <= '9') && (*str >= '0'))
  81.             ival = 10*ival + *str++ -'0';
  82.     *rtn = neg*ival;
  83.     return str;
  84. }
  85.  
  86. /* this routine fixes the names that are generated by C++, ".this" is a good
  87.  * example.  The period does not work for the debugger, since it looks like
  88.  * the syntax for a structure element, and thus it gets mightily confused
  89.  */
  90. static fix_name(char* pnt){
  91.     for( ;*pnt != 0; pnt++){
  92.     if(*pnt == '.') *pnt = '$';
  93.     };
  94. }
  95.  
  96. /* this routine is used to compare the names of certain types to various
  97.  * fixed types that are known by the debugger.
  98.  */
  99. #define type_check(x)  !strcmp( symbol_name , x )
  100.  
  101. /* When defining a structure, this routine is called to find the name of
  102.  * the actual structure.  It is assumed that str points to the equal sign
  103.  * in the definition, and it moves backward until it finds the start of the
  104.  * name.  If it finds a 0, then it knows that this structure def is in the
  105.  * outermost level, and thus symbol_name points to the symbol name.
  106.  */
  107. static char* get_struct_name(char* str){
  108.     char* pnt;
  109.     pnt=str;
  110.     while((*pnt != ':') && (*pnt != '\0')) pnt--;
  111.     if(*pnt == '\0') return symbol_name;
  112.     *pnt-- = '\0';
  113.     while((*pnt != ';') && (*pnt != '=')) pnt--;
  114.     if(*pnt == ';') return pnt+1;
  115.     while((*pnt < '0') || (*pnt > '9')) pnt++;
  116.     while((*pnt >= '0') && (*pnt <= '9')) pnt++;
  117.     return pnt;
  118. }    
  119. /* search symbol list for type number dbx_type.  Return a pointer to struct */
  120. static struct VMS_DBG_Symbol* find_symbol(int dbx_type){
  121.     struct VMS_DBG_Symbol* spnt;
  122.     spnt=VMS_Symbol_type_list;
  123.     while (spnt!=(struct VMS_DBG_Symbol*) NULL){
  124.         if(spnt->dbx_type==dbx_type) break;
  125.         spnt=spnt->next;};
  126.     if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
  127.     return spnt;
  128. }
  129.  
  130.  
  131. /* Many good programmers cringe when they see a fixed size array - since I am
  132.  * using this to generate the various descriptors for the data types present,
  133.  * you might argue that the descriptor could overflow the array for a
  134.  * complicated variable, and then I am in deep doo-doo.  My answer to this is
  135.  * that the debugger records that we write have all sorts of length bytes
  136.  * stored in them all over the place, and if we exceed 127 bytes (since the top
  137.  * bit indicates data, rather than a command), we are dead anyhow.  So I figure
  138.  * why not do this the easy way.  Besides, to get 128 bytes, you need something
  139.  * like an array with 10 indicies, or something like
  140.  *       char **************************************** var; 
  141.  * Lets get real.  If some idiot writes programs like that he/she gets what
  142.  * they deserve.  (It is possible to overflow the record with a somewhat
  143.  * simpler example, like: int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
  144.  * but still...).  And if someone in the peanut gallery wants to know "What
  145.  * does VAX-C do with something like this?", I will tell you.  It crashes.
  146.  * At least this code has the good sense to convert it to *void.
  147.  * In practice, I do not think that this presents too much of a problem, since
  148.  * struct/union/enum all use defined types, which sort of terminate the
  149.  * definition.  It occurs to me that we could possibly do the same thing with
  150.  * arrays and pointers, but I don't know quite how it would be coded.
  151.  *
  152.  * And now back to the regularly scheduled program...
  153.  */
  154. #define MAX_DEBUG_RECORD 128
  155. static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
  156. static int Lpnt;        /* index into Local */
  157. static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
  158. static int Apoint;    /* index into Asuffix */
  159. static char overflow;    /* flag to indicate we have written too much*/
  160. static int total_len;    /* used to calculate the total length of variable
  161.             descriptor plus array descriptor - used for len byte*/
  162. static int struct_number;    /* counter used to assign indexes to struct
  163.                     unions and enums */
  164.  
  165. /* this routine puts info into either Local or Asuffix, depending on the sign
  166.  * of size.  The reason is that it is easier to build the variable descriptor
  167.  * backwards, while the array descriptor is best built forwards.  In the end
  168.  * they get put together, if there is not a struct/union/enum along the way
  169.  */
  170. push(int value, int size){
  171.     char * pnt;
  172.     int i;
  173.     int size1;
  174.     long int val;
  175.     val=value;
  176.     pnt=(char*) &val;
  177.     size1 = size;
  178.     if (size < 0) {size1 = -size; pnt += size1-1;};
  179.     if(size < 0)
  180.     for(i=0;i<size1;i++) {
  181.         Local[Lpnt--] = *pnt--;
  182.         if(Lpnt < 0) {overflow = 1; Lpnt = 1;};}
  183.     else for(i=0;i<size1;i++){
  184.          Asuffix[Apoint++] = *pnt++;
  185.          if(Apoint >= MAX_DEBUG_RECORD) 
  186.             {overflow = 1; Apoint =MAX_DEBUG_RECORD-1;};}
  187. }
  188.  
  189. /* this routine generates the array descriptor for a given array */
  190. static array_suffix(struct VMS_DBG_Symbol* spnt2){
  191.     struct VMS_DBG_Symbol * spnt;
  192.     struct VMS_DBG_Symbol * spnt1;
  193.     int rank;
  194.     int total_size;
  195.     int i;
  196.     rank=0;
  197.     spnt=spnt2;
  198.     while(spnt->advanced != ARRAY) {
  199.         spnt=find_symbol(spnt->type2);
  200.         if(spnt == (struct VMS_DBG_Symbol *) NULL) return;};
  201.     spnt1=spnt;
  202.     spnt1=spnt;
  203.     total_size= 1;
  204.     while(spnt1->advanced == ARRAY) {rank++;
  205.         total_size *= (spnt1->index_max - spnt1->index_min +1);
  206.         spnt1=find_symbol(spnt1->type2);};
  207.     total_size = total_size * spnt1->data_size;
  208.     push(spnt1->data_size,2);
  209.     if(spnt1->VMS_type == 0xa3) push(0,1);
  210.             else push(spnt1->VMS_type,1);
  211.     push(4,1);
  212.     for(i=0;i<6;i++) push(0,1);
  213.     push(0xc0,1);
  214.     push(rank,1);
  215.     push(total_size,4);
  216.     push(0,4);
  217.     spnt1=spnt;
  218.     while(spnt1->advanced == ARRAY) {
  219.         push(spnt1->index_max - spnt1->index_min+1,4);
  220.         spnt1=find_symbol(spnt1->type2);};
  221.     spnt1=spnt;
  222.     while(spnt1->advanced == ARRAY) {
  223.         push(spnt1->index_min,4);
  224.         push(spnt1->index_max,4);
  225.         spnt1=find_symbol(spnt1->type2);};
  226. }
  227.  
  228. /* this routine generates the start of a variable descriptor based upon
  229.  * a struct/union/enum that has yet to be defined.  We define this spot as
  230.  * a new location, and save four bytes for the address.  When the struct is
  231.  * finally defined, then we can go back and plug in the correct address
  232. */
  233. static new_forward_ref(int dbx_type){
  234.     struct forward_ref* fpnt;
  235.     fpnt = (struct forward_ref*) malloc(sizeof(struct forward_ref));
  236.     fpnt->next = f_ref_root;
  237.     f_ref_root = fpnt;
  238.     fpnt->dbx_type = dbx_type;
  239.     fpnt->struc_numb = ++structure_count;
  240.     fpnt->resolved = 'N';
  241.     push(3,-1);
  242.     total_len = 5;
  243.     push(total_len,-2);
  244.     struct_number = - fpnt->struc_numb;
  245. }
  246.  
  247. /* this routine generates the variable descriptor used to describe non-basic
  248.  * variables.  It calls itself recursively until it gets to the bottom of it
  249.  * all, and then builds the descriptor backwards.  It is easiest to do it this
  250.  *way since we must periodically write length bytes, and it is easiest if we know
  251.  *the value when it is time to write it.
  252.  */
  253. static int gen1(struct VMS_DBG_Symbol * spnt,int array_suffix_len){
  254.     struct VMS_DBG_Symbol * spnt1;
  255.     int i;
  256.     switch(spnt->advanced){
  257.     case VOID:
  258.         push(DBG$C_VOID,-1);
  259.         total_len += 1;
  260.         push(total_len,-2);
  261.         return 0;
  262.     case BASIC:
  263.     case FUNCTION:
  264.         if(array_suffix_len == 0) {
  265.                 push(spnt->VMS_type,-1);
  266.                 push(DBG$C_BASIC,-1);        
  267.                 total_len = 2;
  268.                 push(total_len,-2);
  269.                 return 1;};
  270.         push(0,-4);
  271.         push(0xfa02,-2);        
  272.         total_len = -2;
  273.         return 1;
  274.     case STRUCT:
  275.     case UNION:
  276.     case ENUM:
  277.         struct_number=spnt->struc_numb;
  278.         if(struct_number < 0) {
  279.             new_forward_ref(spnt->dbx_type);
  280.             return 1;
  281.         }
  282.         push(DBG$C_STRUCT,-1);
  283.         total_len = 5;
  284.         push(total_len,-2);
  285.         return 1;
  286.     case POINTER:
  287.         spnt1=find_symbol(spnt->type2);
  288.         i=1;
  289.         if(spnt1 == (struct VMS_DBG_Symbol *) NULL)    
  290.             new_forward_ref(spnt->type2);
  291.         else  i=gen1(spnt1,0);
  292.         if(i){ /* (*void) is a special case, do not put pointer suffix*/
  293.           push(DBG$C_POINTER,-1);
  294.           total_len += 3;
  295.           push(total_len,-2);
  296.         };
  297.         return 1;
  298.     case ARRAY:
  299.         spnt1=spnt;
  300.         while(spnt1->advanced == ARRAY)
  301.             {spnt1 = find_symbol(spnt1->type2);
  302.             if(spnt1 == (struct VMS_DBG_Symbol *) NULL) {
  303.                 printf("gcc-as warning(debugger output):");
  304.                 printf("Forward reference error, dbx type %d\n",
  305.                     spnt->type2);
  306.                 return;}
  307.             };
  308. /* It is too late to generate forward references, so the user gets a message.
  309.  * This should only happen on a compiler error */
  310.         i=gen1(spnt1,1);
  311.         i=Apoint;
  312.         array_suffix(spnt);
  313.         array_suffix_len = Apoint - i;
  314.         switch(spnt1->advanced){
  315.         case BASIC:
  316.         case FUNCTION:
  317.             break;
  318.         default:
  319.             push(0,-2);
  320.             total_len += 2;
  321.             push(total_len,-2);
  322.             push(0xfa,-1);
  323.             push(0x0101,-2);
  324.             push(DBG$C_COMPLEX_ARRAY,-1);
  325.         };
  326.         total_len += array_suffix_len + 8;
  327.         push(total_len,-2);            
  328.     };
  329. }
  330.  
  331. /* this generates a suffix for a variable.  If it is not a defined type yet,
  332.  * then dbx_type contains the type we are expecting so we can generate a
  333.  * forward reference.  This calls gen1 to build most of the descriptor, and
  334.  * then it puts the icing on at the end.  It then dumps whatever is needed
  335.  * to get a complete descriptor (i.e. struct reference, array suffix ).
  336.  */
  337. static generate_suffix(struct VMS_DBG_Symbol * spnt,int dbx_type){
  338.     int ilen;
  339.     int i;
  340.     char pvoid[6] = {5,0xaf,0,1,0,5};
  341.     struct VMS_DBG_Symbol * spnt1;
  342.     Apoint=0;
  343.     Lpnt =MAX_DEBUG_RECORD-1;
  344.     total_len=0;
  345.     struct_number = 0;
  346.     overflow = 0;
  347.     if(spnt == (struct VMS_DBG_Symbol*) NULL)
  348.         new_forward_ref(dbx_type);
  349.     else{
  350.         if(spnt->VMS_type != 0xa3) return 0; /* no suffix needed */
  351.         gen1(spnt,0);
  352.     };
  353.     push(0x00af,-2);
  354.     total_len += 4;
  355.     push(total_len,-1);
  356. /* if the variable descriptor overflows the record, output a descriptor for
  357.  * a pointer to void.
  358.  */
  359.     if((total_len >= MAX_DEBUG_RECORD) || overflow) {
  360.          printf(" Variable descriptor %d too complicated. Defined as *void ",spnt->dbx_type);
  361.          VMS_Store_Immediate_Data(pvoid, 6, OBJ$C_DBG);
  362.           return;
  363.         };        
  364.     i=0;
  365.     while(Lpnt < MAX_DEBUG_RECORD-1) Local[i++] = Local[++Lpnt];
  366.     Lpnt = i; 
  367. /* we use this for a reference to a structure that has already been defined */
  368.     if(struct_number > 0){
  369.          VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0;
  370.          VMS_Store_Struct(struct_number);}; 
  371. /* we use this for a forward reference to a structure that has yet to be
  372. *defined.  We store four bytes of zero to make room for the actual address once
  373. * it is known
  374. */
  375.     if(struct_number < 0){
  376.          struct_number = -struct_number;
  377.           VMS_Store_Immediate_Data(Local, Lpnt,OBJ$C_DBG);Lpnt=0;
  378.           VMS_Def_Struct(struct_number);
  379.          for(i=0;i<4;i++) Local[Lpnt++] = 0;
  380.          VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0;
  381.           };
  382.     i=0;
  383.     while(i<Apoint) Local[Lpnt++] = Asuffix[i++];
  384.     if(Lpnt != 0)
  385.     VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);
  386.     Lpnt=0;
  387.  }
  388.  
  389. /* This routine generates a symbol definition for a C sybmol for the debugger.
  390.  * It takes a psect and offset for global symbols - if psect < 0, then this is
  391.  * a local variable and the offset is relative to FP.  In this case it can
  392.  * be either a variable (Offset < 0) or a parameter (Offset > 0).
  393.  */
  394. VMS_DBG_record(struct VMS_DBG_Symbol* spnt,int Psect,int  Offset, char* Name)
  395. {
  396.     char* pnt;
  397.     int j;
  398.     int maxlen;
  399.     int i=0;
  400.     if(Psect < 0) {    /* this is a local variable, referenced to SP */
  401.       maxlen=7+strlen(Name);
  402.       Local[i++] = maxlen;
  403.       Local[i++]=spnt->VMS_type;
  404.       if(Offset > 0) Local[i++] = DBG$C_FUNCTION_PARAMETER;
  405.         else Local[i++] = DBG$C_LOCAL_SYM;
  406.       pnt=(char*) &Offset;
  407.       for(j=0;j<4;j++) Local[i++]=*pnt++; /* copy the offset */
  408.     } else {
  409.       maxlen=7+strlen(Name); /* symbols fixed in memory */
  410.       Local[i++]=7+strlen(Name);
  411.       Local[i++]=spnt->VMS_type;
  412.       Local[i++]=1;
  413.       VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  414.       VMS_Set_Data(Psect,Offset,OBJ$C_DBG,0);
  415.     }
  416.     Local[i++]=strlen(Name);
  417.     pnt=Name;
  418.     fix_name(pnt);    /* if there are bad characters in name, convert them */
  419.     while(*pnt!='\0') Local[i++]=*pnt++;
  420.     VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);
  421.     if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);
  422. }
  423.  
  424.  
  425. /* This routine parses the stabs entries in order to make the definition
  426.  * for the debugger of local symbols and function parameters
  427.  */
  428. int VMS_local_stab_Parse(symbolS * sp){
  429.     char *pnt;
  430.     char *pnt1;
  431.     char *str;
  432.     struct VMS_DBG_Symbol* spnt;
  433.        struct VMS_Symbol *    vsp;
  434.     int dbx_type;
  435.     int VMS_type;
  436.     dbx_type=0;
  437.     str=sp->sy_nlist.n_un.n_name;
  438.     pnt=(char*) strchr(str,':');
  439.     if(pnt==(char*) NULL) return;    /* no colon present */
  440.     pnt1=pnt++;    /* save this for later, and skip colon */
  441.     if(*pnt == 'c') return 0;    /* ignore static constants */
  442. /* there is one little catch that we must be aware of.  Sometimes function
  443.  * parameters are optimized into registers, and the compiler, in its infiite
  444.  * wisdom outputs stabs records for *both*.  In general we want to use the
  445.  * register if it is present, so we must search the rest of the symbols for 
  446.  * this function to see if this parameter is assigned to a register.
  447.  */
  448.     {
  449.     char *str1;
  450.     char *pnt2;
  451.     symbolS * sp1;
  452.     if(*pnt == 'p'){
  453.       for(sp1 = sp->sy_next; sp1; sp1 = sp1->sy_next) {
  454.         if ((sp1->sy_nlist.n_type & N_STAB) == 0) continue;
  455.         if((unsigned char)sp1->sy_nlist.n_type == N_FUN) break;
  456.         if((unsigned char)sp1->sy_nlist.n_type != N_RSYM) continue;
  457.         str1=sp1->sy_nlist.n_un.n_name;    /* and get the name */
  458.         pnt2=str;
  459.         while(*pnt2 != ':') {
  460.         if(*pnt2 != *str1) break;
  461.         pnt2++; str1++;};
  462.         if((*str1 != ':') || (*pnt2 != ':') ) continue;
  463.         return;    /* they are the same!  lets skip this one */
  464.       }; /* for */
  465. /* first find the dbx symbol type from list, and then find VMS type */
  466.       pnt++;    /* skip p in case no register */
  467.     };/* if */ }; /* p block */
  468.     pnt = cvt_integer( pnt, &dbx_type);
  469.     spnt = find_symbol(dbx_type);
  470.     if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
  471.     *pnt1='\0';
  472.     VMS_DBG_record(spnt,-1,sp->sy_nlist.n_value,str);
  473.     *pnt1=':';    /* and restore the string */
  474.     return 1;
  475. }
  476.  
  477. /* this routine parses a stabs entry to find the information required to define
  478.  * a variable.  It is used for global and static variables. 
  479.  * Basically we need to know the address of the symbol.  With older versions
  480.  * of the compiler, const symbols are
  481.  * treated differently, in that if they are global they are written into the
  482.  * text psect.  The global symbol entry for such a const is actually written
  483.  * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
  484.  * of psects, we must search the entry points as well.  static consts are even
  485.  * harder, since they are never assigned a memory address.  The compiler passes
  486.  * a stab to tell us the value, but I am not sure what to do with it.
  487.  */
  488. static gave_compiler_message = 0;
  489.  
  490. static int VMS_stab_parse(symbolS * sp,char expected_type,
  491.     int type1,int type2,int Text_Psect){
  492.     char *pnt;
  493.     char *pnt1;
  494.     char *str;
  495.     symbolS * sp1;
  496.     struct VMS_DBG_Symbol* spnt;
  497.        struct VMS_Symbol *    vsp;
  498.     int dbx_type;
  499.     int VMS_type;
  500.     dbx_type=0;
  501.     str=sp->sy_nlist.n_un.n_name;
  502.     pnt=(char*) strchr(str,':');
  503.     if(pnt==(char*) NULL) return;    /* no colon present */
  504.     pnt1=pnt;    /* save this for later*/
  505.     pnt++;
  506.     if(*pnt==expected_type){
  507.         pnt = cvt_integer(pnt+1,&dbx_type);
  508.         spnt = find_symbol(dbx_type);
  509.         if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
  510. /* now we need to search the symbol table to find the psect and offset for
  511.  * this variable.
  512.  */
  513.     *pnt1='\0';
  514.     vsp=VMS_Symbols;
  515.     while(vsp != (struct VMS_Symbol*) NULL) 
  516.       {pnt=vsp->Symbol->sy_nlist.n_un.n_name;
  517.        if(pnt!=(char*) NULL)  if(*pnt++ == '_') 
  518. /* make sure name is the same, and make sure correct symbol type */
  519.        if((strlen(pnt) == strlen(str)) && (strcmp(pnt,str)==0) 
  520.         && ((vsp->Symbol->sy_type == type1) ||
  521.         (vsp->Symbol->sy_type == type2))) break;
  522.             vsp=vsp->Next;};
  523.         if(vsp != (struct VMS_Symbol*) NULL){
  524.         VMS_DBG_record(spnt,vsp->Psect_Index,vsp->Psect_Offset,str);
  525.         *pnt1=':';    /* and restore the string */
  526.         return 1;};
  527. /* the symbol was not in the symbol list, but it may be an "entry point"
  528.    if it was a constant */
  529.        for(sp1 = symbol_rootP; sp1; sp1 = sp1->sy_next) {
  530.           /*
  531.            *    Dispatch on STAB type
  532.            */
  533.           if(sp1->sy_type != (N_TEXT | N_EXT) && sp1->sy_type!=N_TEXT)
  534.               continue;
  535.           pnt = sp1->sy_nlist.n_un.n_name;
  536.           if(*pnt == '_') pnt++;
  537.           if(strcmp(pnt,str) == 0){
  538.             if(!gave_compiler_message && expected_type=='G'){
  539. printf("***Warning - the assembly code generated by the compiler has placed\n");
  540. printf("global constant(s) in the text psect.  These will not be available to\n");
  541. printf("other modules, since this is not the correct way to handle this. You\n");
  542. printf("have two options: 1) get a patched compiler that does not put global\n");
  543. printf("constants in the text psect, or 2) remove the 'const' keyword from\n");
  544. printf("definitions of global variables in your source module(s).  Don't say\n");
  545. printf("I didn't warn you!");
  546. gave_compiler_message = 1;};
  547.                 VMS_DBG_record(spnt,
  548.                  Text_Psect,
  549.                  sp1->sy_nlist.n_value,
  550.                  str);
  551.              *pnt1=':';
  552.              *(sp1->sy_nlist.n_un.n_name) = 'L';
  553.                     /* fool assembler to not output this
  554.                      * as a routine in the TBT */
  555.             return 1;};
  556.         };
  557.     };
  558.     *pnt1=':';    /* and restore the string */
  559.     return 0;
  560. }
  561.  
  562.  
  563. VMS_GSYM_Parse(symbolS * sp,int Text_Psect){ /* Global variables */
  564.     VMS_stab_parse(sp,'G',(N_UNDF | N_EXT),(N_DATA | N_EXT),Text_Psect);
  565. }
  566.  
  567.  
  568. VMS_LCSYM_Parse(symbolS * sp,int Text_Psect){/* Static symbols - uninitialized */
  569.     VMS_stab_parse(sp,'S',N_BSS,-1,Text_Psect);
  570. }
  571.  
  572. VMS_STSYM_Parse(symbolS * sp,int Text_Psect){ /*Static symbols - initialized */
  573.     VMS_stab_parse(sp,'S',N_DATA,-1,Text_Psect);
  574. }
  575.  
  576.  
  577. /* for register symbols, we must figure out what range of addresses within the
  578.  * psect are valid. We will use the brackets in the stab directives to give us
  579.  * guidance as to the PC range that this variable is in scope.  I am still not
  580.  * completely comfortable with this but as I learn more, I seem to get a better
  581.  * handle on what is going on.
  582.  * Caveat Emptor.
  583.  */
  584. VMS_RSYM_Parse(symbolS * sp,symbolS * Current_Routine,int Text_Psect){
  585.     char* pnt;
  586.     char* pnt1;
  587.     char* str;
  588.     int dbx_type;
  589.     struct VMS_DBG_Symbol* spnt;
  590.     int j;
  591.     int maxlen;
  592.     int i=0;
  593.     int bcnt=0;
  594.     int Min_Offset=-1;    /* min PC of validity */
  595.     int Max_Offset=0; /* max PC of validity */
  596.     symbolS * symbolP;
  597.        for(symbolP = sp; symbolP; symbolP = symbolP->sy_next) {
  598.           /*
  599.            *    Dispatch on STAB type
  600.            */
  601.           switch((unsigned char)symbolP->sy_type) {
  602.              case N_LBRAC:
  603.                 if(bcnt++==0) Min_Offset = symbolP->sy_nlist.n_value;
  604.                 break;
  605.              case N_RBRAC:
  606.                 if(--bcnt==0) Max_Offset = 
  607.                     symbolP->sy_nlist.n_value-1;
  608.                 break;
  609.            }
  610.        if((Min_Offset != -1) && (bcnt == 0)) break;
  611.        if((unsigned char)symbolP->sy_type == N_FUN) break;
  612.         }
  613. /* check to see that the addresses were defined.  If not, then there were no
  614.  * brackets in the function, and we must try to search for the next function
  615.  * Since functions can be in any order, we should search all of the symbol list
  616.  * to find the correct ending address. */
  617.     if(Min_Offset == -1){
  618.       int Max_Source_Offset;
  619.       int This_Offset;
  620.       Min_Offset = sp->sy_nlist.n_value;
  621.        for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) {
  622.           /*
  623.            *    Dispatch on STAB type
  624.            */
  625.           This_Offset = symbolP->sy_nlist.n_value;
  626.           switch(symbolP->sy_type) {
  627.               case N_TEXT | N_EXT:
  628.             if((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
  629.                     Max_Offset = This_Offset;
  630.                 break;
  631.              case N_SLINE:
  632.             if(This_Offset > Max_Source_Offset)
  633.                 Max_Source_Offset=This_Offset;
  634.            }
  635.         }
  636. /* if this is the last routine, then we use the PC of the last source line
  637.  * as a marker of the max PC for which this reg is valid */
  638.       if(Max_Offset == 0x7fffffff) Max_Offset = Max_Source_Offset;
  639.     };
  640.     dbx_type=0;
  641.     str=sp->sy_nlist.n_un.n_name;
  642.     pnt=(char*) strchr(str,':');
  643.     if(pnt==(char*) NULL) return;    /* no colon present */
  644.     pnt1=pnt;    /* save this for later*/
  645.     pnt++;
  646.     if(*pnt!='r') return 0;
  647.     pnt = cvt_integer( pnt+1, &dbx_type);
  648.     spnt = find_symbol(dbx_type);
  649.     if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is yet*/
  650.     *pnt1='\0';
  651.     maxlen=25+strlen(sp->sy_nlist.n_un.n_name);
  652.     Local[i++]=maxlen;
  653.     Local[i++]=spnt->VMS_type;
  654.     Local[i++]=0xfb;
  655.     Local[i++]=strlen(sp->sy_nlist.n_un.n_name)+1;
  656.     Local[i++]=0x00;
  657.     Local[i++]=0x00;
  658.     Local[i++]=0x00;
  659.     Local[i++]=strlen(sp->sy_nlist.n_un.n_name);
  660.     pnt=sp->sy_nlist.n_un.n_name;
  661.     fix_name(pnt);    /* if there are bad characters in name, convert them */
  662.     while(*pnt!='\0') Local[i++]=*pnt++;
  663.     Local[i++]=0xfd;
  664.     Local[i++]=0x0f;
  665.     Local[i++]=0x00;
  666.     Local[i++]=0x03;
  667.     Local[i++]=0x01;
  668.     VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  669.     VMS_Set_Data(Text_Psect,Min_Offset,OBJ$C_DBG,1);
  670.     VMS_Set_Data(Text_Psect,Max_Offset,OBJ$C_DBG,1);
  671.     Local[i++]=0x03;
  672.     Local[i++]=sp->sy_nlist.n_value;
  673.     Local[i++]=0x00;
  674.     Local[i++]=0x00;
  675.     Local[i++]=0x00;
  676.     VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);
  677.     *pnt1=':';
  678.     if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);
  679. }
  680.  
  681. /* this function examines a structure definition, checking all of the elements
  682.  * to make sure that all of them are fully defined.  The only thing that we
  683.  * kick out are arrays of undefined structs, since we do not know how big
  684.  * they are.  All others we can handle with a normal forward reference.
  685.  */
  686. static int forward_reference(char* pnt){
  687.     int i;
  688.     struct VMS_DBG_Symbol * spnt;
  689.     struct VMS_DBG_Symbol * spnt1;
  690.     pnt = cvt_integer(pnt+1,&i);
  691.     if(*pnt == ';') return 0; /* no forward references */
  692.     do{
  693.       pnt=(char*) strchr(pnt,':');
  694.       pnt = cvt_integer(pnt+1,&i);
  695.       spnt = find_symbol(i);
  696.       if(spnt == (struct VMS_DBG_Symbol*) NULL) return 0;
  697.       while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY)){
  698.           i=spnt->type2;
  699.           spnt1 = find_symbol(spnt->type2);
  700.           if((spnt->advanced == ARRAY) &&
  701.             (spnt1 == (struct VMS_DBG_Symbol*) NULL))return 1;
  702.           if(spnt1 == (struct VMS_DBG_Symbol*) NULL) break;
  703.           spnt=spnt1;
  704.       };
  705.       pnt = cvt_integer(pnt+1,&i);
  706.       pnt = cvt_integer(pnt+1,&i);
  707.     }while(*++pnt != ';');
  708.     return 0;    /* no forward refences found */
  709. }
  710.  
  711. /* This routine parses the stabs directives to find any definitions of dbx type
  712.  * numbers.  It makes a note of all of them, creating a structure element
  713.  * of VMS_DBG_Symbol that describes it.  This also generates the info for the
  714.  * debugger that describes the struct/union/enum, so that further references
  715.  * to these data types will be by number
  716.  *     We have to process pointers right away, since there can be references
  717.  * to them later in the same stabs directive.  We cannot have forward
  718.  * references to pointers, (but we can have a forward reference to a pointer to
  719.  * a structure/enum/union) and this is why we process them immediately.
  720.  * After we process the pointer, then we search for defs that are nested even
  721.  * deeper.
  722.  */
  723. static int VMS_typedef_parse(char* str){
  724.     char* pnt;
  725.     char* pnt1;
  726.     char* pnt2;
  727.     int i;
  728.     int dtype;
  729.     struct forward_ref * fpnt;
  730.     int i1,i2,i3;
  731.     int convert_integer;
  732.     struct VMS_DBG_Symbol* spnt;
  733.     struct VMS_DBG_Symbol* spnt1;
  734. /* check for any nested def's */
  735.     pnt=(char*)strchr(str+1,'=');
  736.     if((pnt != (char*) NULL) && (*(str+1) != '*')) 
  737.         if(VMS_typedef_parse(pnt) == 1 ) return 1;
  738. /* now find dbx_type of entry */
  739.     pnt=str-1;
  740.     if(*pnt == 'c'){    /* check for static constants */
  741.         *str = '\0';    /* for now we ignore them */
  742.         return 0;};
  743.     while((*pnt <= '9')&& (*pnt >= '0')) pnt--;
  744.     pnt++;    /* and get back to the number */
  745.     cvt_integer(pnt,&i1);
  746.     spnt = find_symbol(i1);
  747. /* first we see if this has been defined already, due to a forward reference*/
  748.     if(spnt == (struct VMS_DBG_Symbol*) NULL) {
  749.       if(VMS_Symbol_type_list==(struct VMS_DBG_Symbol*) NULL)
  750.         {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol));
  751.          spnt->next = (struct VMS_DBG_Symbol*) NULL;
  752.         VMS_Symbol_type_list=spnt;}
  753.       else
  754.         {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol));
  755.         spnt->next=VMS_Symbol_type_list;
  756.         VMS_Symbol_type_list = spnt;};
  757.       spnt->dbx_type = i1;    /* and save the type */
  758.     };
  759. /* for structs and unions, do a partial parse, otherwise we sometimes get
  760.  * circular definitions that are impossible to resolve. We read enough info
  761.  * so that any reference to this type has enough info to be resolved 
  762.  */
  763.     pnt=str + 1;    /* point to character past equal sign */
  764.     if((*pnt == 'u') || (*pnt == 's')){
  765.     };
  766.     if((*pnt <= '9') && (*pnt >= '0')){
  767.        if(type_check("void")){ /* this is the void symbol */
  768.         *str='\0';
  769.         spnt->advanced = VOID;
  770.         return 0;};
  771.        printf("gcc-as warning(debugger output):");
  772.        printf(" %d is an unknown untyped variable.\n",spnt->dbx_type);
  773.        return 1;    /* do not know what this is */
  774.     };
  775. /* now define this module*/
  776.     pnt=str + 1;    /* point to character past equal sign */
  777.     switch (*pnt){
  778.         case 'r':
  779.         spnt->advanced= BASIC;
  780.         if(type_check("int")) {
  781.             spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;}
  782.         else if(type_check("long int")) {
  783.             spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;}
  784.         else if(type_check("unsigned int")) {
  785.             spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;}
  786.         else if(type_check("long unsigned int")) {
  787.             spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;}
  788.         else if(type_check("short int")) {
  789.             spnt->VMS_type=DBG$C_SSINT; spnt->data_size = 2;}
  790.         else if(type_check("short unsigned int")) {
  791.             spnt->VMS_type=DBG$C_USINT; spnt->data_size = 2;}
  792.         else if(type_check("char")) {
  793.             spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;}
  794.         else if(type_check("signed char")) {
  795.             spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;}
  796.         else if(type_check("unsigned char")) {
  797.             spnt->VMS_type=DBG$C_UCHAR; spnt->data_size = 1;}
  798.         else if(type_check("float")) {
  799.             spnt->VMS_type=DBG$C_REAL4; spnt->data_size = 4;}
  800.         else if(type_check("double")) {
  801.             spnt->VMS_type=DBG$C_REAL8; spnt->data_size = 8;}
  802.         pnt1=(char*) strchr(str,';')+1;
  803.         break;
  804.         case 's':
  805.         case 'u':
  806.         if(*pnt == 's') spnt->advanced= STRUCT;
  807.                 else spnt->advanced= UNION;
  808.         spnt->VMS_type = DBG$C_ADVANCED_TYPE;
  809.         pnt1 = cvt_integer(pnt+1,&spnt->data_size);
  810.         if(forward_reference(pnt)) {
  811.             spnt->struc_numb = -1;
  812.             return 1;
  813.         }
  814.         spnt->struc_numb = ++structure_count;
  815.         pnt1--;
  816.         pnt=get_struct_name(str);
  817.         VMS_Def_Struct(spnt->struc_numb);
  818.         fpnt = f_ref_root;
  819.         while(fpnt != (struct forward_ref*) NULL){
  820.             if(fpnt->dbx_type == spnt->dbx_type) {
  821.                 fpnt->resolved = 'Y';
  822.                 VMS_Set_Struct(fpnt->struc_numb);
  823.                 VMS_Store_Struct(spnt->struc_numb);};
  824.             fpnt = fpnt->next;};
  825.         VMS_Set_Struct(spnt->struc_numb);
  826.         i=0;
  827.         Local[i++] = 11+strlen(pnt);
  828.         Local[i++] = DBG$C_STRUCT_START;
  829.         Local[i++] = 0x80;
  830.         for(i1=0;i1<4;i1++) Local[i++] = 0x00;
  831.         Local[i++] = strlen(pnt);
  832.         pnt2=pnt;
  833.         while(*pnt2 != '\0') Local[i++] = *pnt2++;
  834.         i2=spnt->data_size * 8;        /* number of bits */
  835.         pnt2=(char*) &i2;
  836.         for(i1=0;i1<4;i1++) Local[i++] = *pnt2++;
  837.         VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  838.         if(pnt != symbol_name) {
  839.             pnt += strlen(pnt);
  840.             *pnt=':';};    /* replace colon for later */
  841.         while(*++pnt1 != ';'){
  842.           pnt=(char*) strchr(pnt1,':');
  843.           *pnt='\0';
  844.           pnt2=pnt1;
  845.           pnt1 = cvt_integer(pnt+1,&dtype);
  846.           pnt1 = cvt_integer(pnt1+1,&i2);
  847.           pnt1 = cvt_integer(pnt1+1,&i3);
  848.           if((dtype == 1) && (i3 != 32)) { /* bitfield */
  849.             Apoint = 0;
  850.             push(19+strlen(pnt2),1);
  851.             push(0xfa22,2);
  852.             push(1+strlen(pnt2),4);
  853.             push(strlen(pnt2),1);
  854.             while(*pnt2 != '\0') push(*pnt2++,1);
  855.             push(i3,2);    /* size of bitfield */
  856.             push(0x0d22,2);
  857.             push(0x00,4);
  858.             push(i2,4);    /* start position */
  859.             VMS_Store_Immediate_Data(Asuffix,Apoint,OBJ$C_DBG);
  860.             Apoint=0;
  861.           }else{
  862.             Local[i++] = 7+strlen(pnt2);
  863.             spnt1 = find_symbol(dtype);
  864.         /* check if this is a forward reference */
  865.             if(spnt1 != (struct VMS_DBG_Symbol*) NULL)
  866.                  Local[i++] = spnt1->VMS_type;
  867.             else
  868.                  Local[i++] = DBG$C_ADVANCED_TYPE;
  869.             Local[i++] = DBG$C_STRUCT_ITEM;
  870.             pnt=(char*) &i2;        
  871.             for(i1=0;i1<4;i1++) Local[i++] = *pnt++;
  872.             Local[i++] = strlen(pnt2);
  873.             while(*pnt2 != '\0') Local[i++] = *pnt2++;
  874.             VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  875.             if(spnt1 == (struct VMS_DBG_Symbol*) NULL)
  876.                 generate_suffix(spnt1,dtype);
  877.             else if(spnt1->VMS_type == DBG$C_ADVANCED_TYPE)
  878.                 generate_suffix(spnt1,0);
  879.         };
  880.         };
  881.         pnt1++;
  882.         Local[i++] = 0x01;    /* length byte */
  883.         Local[i++] = DBG$C_STRUCT_END;
  884.         VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  885.         break;
  886.         case 'e':
  887.         spnt->advanced= ENUM;
  888.         spnt->VMS_type = DBG$C_ADVANCED_TYPE;
  889.         spnt->struc_numb = ++structure_count;
  890.         spnt->data_size=4;
  891.         VMS_Def_Struct(spnt->struc_numb);
  892.         fpnt = f_ref_root;
  893.         while(fpnt != (struct forward_ref*) NULL){
  894.             if(fpnt->dbx_type == spnt->dbx_type) {
  895.                 fpnt->resolved = 'Y';
  896.                 VMS_Set_Struct(fpnt->struc_numb);
  897.                 VMS_Store_Struct(spnt->struc_numb);};
  898.             fpnt = fpnt->next;};
  899.         VMS_Set_Struct(spnt->struc_numb);
  900.         i=0;
  901.         Local[i++] = 3+strlen(symbol_name);
  902.         Local[i++] = DBG$C_ENUM_START;
  903.         Local[i++] = 0x20;
  904.         Local[i++] = strlen(symbol_name);
  905.         pnt2=symbol_name;
  906.         while(*pnt2 != '\0') Local[i++] = *pnt2++;
  907.         VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  908.         while(*++pnt != ';') {
  909.           pnt1=(char*) strchr(pnt,':');
  910.           *pnt1++='\0';
  911.           pnt1 = cvt_integer(pnt1,&i1);
  912.           Local[i++] = 7+strlen(pnt);
  913.           Local[i++] = DBG$C_ENUM_ITEM;
  914.           Local[i++] = 0x00;
  915.           pnt2=(char*) &i1;
  916.           for(i2=0;i2<4;i2++) Local[i++] = *pnt2++;
  917.           Local[i++] = strlen(pnt);
  918.           pnt2=pnt;
  919.           while(*pnt != '\0') Local[i++] = *pnt++;
  920.           VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  921.           pnt= pnt1;    /* Skip final semicolon */
  922.         };
  923.         Local[i++] = 0x01; /* len byte */
  924.         Local[i++] = DBG$C_ENUM_END;
  925.         VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
  926.         pnt1=pnt + 1;
  927.         break;
  928.         case 'a':
  929.         spnt->advanced= ARRAY;
  930.         spnt->VMS_type = DBG$C_ADVANCED_TYPE;
  931.         pnt=(char*)strchr(pnt,';');  if (pnt == (char*) NULL) return 1;
  932.         pnt1 = cvt_integer(pnt+1,&spnt->index_min);
  933.         pnt1 = cvt_integer(pnt1+1,&spnt->index_max);
  934.         pnt1 = cvt_integer(pnt1+1,&spnt->type2);
  935.         break;
  936.         case 'f':
  937.         spnt->advanced= FUNCTION;
  938.         spnt->VMS_type = DBG$C_FUNCTION_ADDR;
  939.             /* this masquerades as a basic type*/
  940.         spnt->data_size=4;
  941.         pnt1 = cvt_integer(pnt+1,&spnt->type2);
  942.         break;
  943.         case '*':
  944.         spnt->advanced= POINTER;
  945.         spnt->VMS_type = DBG$C_ADVANCED_TYPE;
  946.         spnt->data_size=4;
  947.         pnt1 = cvt_integer(pnt+1,&spnt->type2);
  948.         pnt=(char*)strchr(str+1,'=');
  949.         if((pnt != (char*) NULL)) 
  950.             if(VMS_typedef_parse(pnt) == 1 ) return 1;
  951.         break;
  952.         default:
  953.         spnt->advanced= UNKNOWN;
  954.         spnt->VMS_type = 0;
  955.         printf("gcc-as warning(debugger output):");
  956.            printf(" %d is an unknown type of variable.\n",spnt->dbx_type);
  957.         return 1; /* unable to decipher */
  958.     };
  959. /* this removes the evidence of the definition so that the outer levels of 
  960. parsing do not have to worry about it */
  961.     pnt=str;
  962.     while (*pnt1 != '\0') *pnt++ = *pnt1++;
  963.     *pnt = '\0';
  964.     return 0;
  965. }
  966.  
  967.  
  968. /* 
  969.  * This is the root routine that parses the stabs entries for definitions.
  970.  * it calls VMS_typedef_parse, which can in turn call itself.
  971.  * We need to be careful, since sometimes there are forward references to
  972.  * other symbol types, and these cannot be resolved until we have completed
  973.  * the parse.
  974.  */
  975. int VMS_LSYM_Parse(){
  976.     char *pnt;
  977.     char *pnt1;
  978.     char *pnt2;
  979.     char *str;
  980.     char fixit[10];
  981.     int incomplete,i,pass,incom1;
  982.     struct VMS_DBG_Symbol* spnt;
  983.        struct VMS_Symbol *    vsp;
  984.     struct forward_ref * fpnt;
  985.     symbolS * sp;
  986.     pass=0;
  987.     incomplete = 0;
  988.        do{
  989.        incom1=incomplete;
  990.        incomplete = 0;
  991.        for(sp = symbol_rootP; sp; sp = sp->sy_next) {
  992.         /*
  993.          *    Deal with STAB symbols
  994.          */
  995.         if ((sp->sy_nlist.n_type & N_STAB) != 0) {
  996.           /*
  997.            *    Dispatch on STAB type
  998.            */
  999.           switch((unsigned char)sp->sy_nlist.n_type) {
  1000.             case N_GSYM:
  1001.             case N_LCSYM:
  1002.             case N_STSYM:
  1003.              case N_PSYM:
  1004.              case N_RSYM:
  1005.             case N_LSYM:
  1006.             case N_FUN:    /*sometimes these contain typedefs*/
  1007.                 str=sp->sy_nlist.n_un.n_name;
  1008.                 symbol_name = str;
  1009.                 pnt=(char*)strchr(str,':');
  1010.                 if(pnt== (char*) NULL) break;
  1011.                 *pnt='\0';
  1012.                 pnt1=pnt+1;
  1013.                 pnt2=(char*)strchr(pnt1,'=');
  1014.                 if(pnt2 == (char*) NULL){
  1015.                         *pnt=':';    /* replace colon */
  1016.                         break;};    /* no symbol here */
  1017.                 incomplete += VMS_typedef_parse(pnt2);
  1018.                 *pnt=':';    /* put back colon so variable def code finds dbx_type*/
  1019.                 break;
  1020.           }    /*switch*/
  1021.         }    /* if */
  1022.        }        /*for*/
  1023.     pass++;
  1024.     } while((incomplete != 0) && (incomplete != incom1 ));
  1025.             /* repeat until all refs resolved if possible */
  1026. /*    if(pass > 1) printf(" Required %d passes\n",pass);*/
  1027.     if(incomplete != 0){    
  1028.         printf("gcc-as warning(debugger output):");
  1029.         printf("Unable to resolve %d circular references.\n",incomplete);
  1030.         };
  1031.     fpnt = f_ref_root;
  1032.     symbol_name="\0";
  1033.     while(fpnt != (struct forward_ref*) NULL){
  1034.         if(fpnt->resolved != 'Y') {
  1035.           if( find_symbol(fpnt->dbx_type) != 
  1036.             (struct VMS_DBG_Symbol*) NULL){
  1037.                 printf("gcc-as warning(debugger output):");
  1038.                 printf("Forward reference error, dbx type %d\n",
  1039.                     fpnt->dbx_type);
  1040.                 break;};
  1041.           fixit[0]=0;
  1042.           sprintf(&fixit[1],"%d=s4;",fpnt->dbx_type);
  1043.           pnt2=(char*)strchr(&fixit[1],'=');
  1044.           VMS_typedef_parse(pnt2);
  1045.           };
  1046.         fpnt = fpnt->next;};
  1047. }
  1048.  
  1049. static symbolS* Current_Routine;
  1050. static int Text_Psect;
  1051.  
  1052. static Define_Local_Symbols(symbolS* s1,symbolS* s2){
  1053.     symbolS * symbolP1;
  1054.     for(symbolP1 = s1->sy_next; symbolP1 != s2; symbolP1 = symbolP1->sy_next) {
  1055.         if (symbolP1 == (symbolS *)NULL) return;
  1056.         if (symbolP1->sy_nlist.n_type == N_FUN) return;
  1057.         /*
  1058.          *    Deal with STAB symbols
  1059.          */
  1060.         if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
  1061.           /*
  1062.            *    Dispatch on STAB type
  1063.            */
  1064.           switch((unsigned char)symbolP1->sy_nlist.n_type) {
  1065.              case N_LSYM:
  1066.              case N_PSYM:
  1067.                 VMS_local_stab_Parse(symbolP1);
  1068.                 break;
  1069.              case N_RSYM:
  1070.                 VMS_RSYM_Parse(symbolP1,Current_Routine,Text_Psect);
  1071.                  break;
  1072.           }    /*switch*/
  1073.         }    /* if */
  1074.        }        /* for */
  1075. }
  1076.  
  1077. static symbolS* Define_Routine(symbolS* symbolP,int Level){
  1078.     symbolS * sstart;
  1079.     symbolS * symbolP1;
  1080.     char    str[10];
  1081.     char * pnt;
  1082.     int rcount = 0;
  1083.     int Offset;
  1084.     sstart = symbolP;
  1085.     for(symbolP1 = symbolP->sy_next; symbolP1; symbolP1 = symbolP1->sy_next) {
  1086.         if (symbolP1->sy_nlist.n_type == N_FUN) break;
  1087.         /*
  1088.          *    Deal with STAB symbols
  1089.          */
  1090.         if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
  1091.           /*
  1092.            *    Dispatch on STAB type
  1093.            */
  1094.           if((unsigned char)symbolP1->sy_nlist.n_type == N_FUN) break;
  1095.           switch((unsigned char)symbolP1->sy_nlist.n_type) {
  1096.             case N_LBRAC:
  1097.                 if(Level != 0) {
  1098.                    pnt = str +sprintf(str,"$%d",rcount++);
  1099.                    *pnt = '\0';
  1100.                    VMS_TBT_Block_Begin(symbolP1,Text_Psect,str);
  1101.                 };
  1102.                 Offset = symbolP1->sy_nlist.n_value;
  1103.                 Define_Local_Symbols(sstart,symbolP1);
  1104.                 symbolP1 = 
  1105.                     Define_Routine(symbolP1,Level+1);
  1106.                 if(Level != 0)
  1107.                   VMS_TBT_Block_End(symbolP1->sy_nlist.n_value -
  1108.                        Offset);
  1109.                 sstart=symbolP1;
  1110.                 break;
  1111.             case N_RBRAC:
  1112.                 return symbolP1;
  1113.           }    /*switch*/
  1114.         }    /* if */
  1115.        }        /* for */
  1116.     /* we end up here if there were no brackets in this function. Define
  1117. everything */
  1118.     Define_Local_Symbols(sstart,(symbolS *) 0);
  1119. }
  1120.  
  1121. VMS_DBG_Define_Routine(symbolS* symbolP,symbolS* Curr_Routine,int Txt_Psect){
  1122.     Current_Routine = Curr_Routine;
  1123.     Text_Psect = Txt_Psect;
  1124.     Define_Routine(symbolP,0);
  1125. }
  1126.